//
//  SimpleXMLParser.h
//  sad
//
//  Created by Christopher Kemsley on 2/2/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef sad_SimpleXMLParser_h
#define sad_SimpleXMLParser_h

#include "URL.hpp"
#include <map>
#include <vector>
#include <string>
#include "IAAny.hpp"






struct	XMLParser
{
	typedef size_t			Offset ;
	static Offset const		NotFound	=	std::string::npos ;
	
	
	static bool		parse	( URL const & path , Any & xmlModel ) ;
	static Offset	parse	( std::string const & file , Any & xmlModel , Offset startPosition = 0 ) ;
	
	static bool		get		( Any const & xmlModel , std::string const & keyPath , Any & outValue ) ;
	
	
private:
	//static bool		traverse	( Any const & xmlModel , std::vector<std::string> const & path , Offset index , Any & outValue ) ;
} ;







/*
 Implement this to make a parser.
 
 To use:
 
 --- Declare your tag name ---
 
 In the constructor.
 
 --- Implement -parse ---
 
 You'll be given the whole file, the character index at which
 your tag starts, and a reference to a location to put your
 created object.
 
 On return, you should return the character index of the very
 end of your scope (i.e. after your closing tag)
 
 If you're specifying a container, you may call XMLParser :: parse
 recursively to get contained elements.
 
 
 Example:
 
 If your tag is "<string>" and the XMLParser find this tag in the file:
 
 "...<string>Hello World!</string>..."
 
 The string, starting at the index passed as an argument, will look like:
 
 "Hello World!</string>..."
 
 If the passed start index was, for example, 42, you would return 63 (42+21)
 */

struct	XMLParsingAgent
{
	std::string openTag ;	// "<name>"
	
	virtual ~XMLParsingAgent () { }
	
	
protected:
	XMLParsingAgent ( std::string const & name ) ;

	
private:
	friend class XMLParser ;
	static std::vector<XMLParsingAgent*>&	agents () ;
	
	XMLParser::Offset	offsetToOpenTag		( std::string const & string , XMLParser::Offset start = 0 ) ;
	
	// Implement this
	virtual XMLParser::Offset	parse		( std::string const & file , Any & plist , XMLParser::Offset start ) = 0 ;
} ;







struct	XMLParserHelper
{
	// Finds the offset to the first "</" after the start offset
	// Returns the length from start to that offset.
	// If the tag isn't found, the close is XMLParser::NotFound
	static XMLParser::Offset	findNextClose			( std::string const& file , XMLParser::Offset start , XMLParser::Offset & close ) ;
	
	
	// Finds the offset to the first "</" and the first "<" after the start offset
	// Returns the length from open to the close tag. If the first "<" is the close
	// tag, this length will be zero.
	// If the tag isn't found, the close is XMLParser::NotFound
	static XMLParser::Offset	findNextOpenClosePair	( std::string const& file , XMLParser::Offset start , XMLParser::Offset & open , XMLParser::Offset & close ) ;
	
	
	// Finds the offset to the first "</". It then uses this length create a string
	// from 'start' to that offset. It returns the length of the string, not including
	// the closing tag
	static XMLParser::Offset	getImmediateString		( std::string const& file , XMLParser::Offset start , std::string & value ) ;
} ;





#endif
